// main.cpp
#include "modbus_tool.h"
#include <iostream>
#include <csignal>
#include <atomic>

std::atomic<bool> running(true);

void query_callback_test(const uint8_t* buffer,int length){
    uint8_t byte_count = buffer[2];
    std::ostringstream oss;
    oss << "Read response: ";
    for (int i = 3; i < 3 + byte_count; i++) {
        oss << std::hex << std::setw(2) << std::setfill('0') 
            << static_cast<int>(buffer[i]) << " ";
    }
    std::cout << oss.str() << std::endl;
}

void single_callback_test(const uint8_t* buffer,int length){
    uint16_t reg_addr = (buffer[2] << 8) | buffer[3];
    uint16_t reg_value = (buffer[4] << 8) | buffer[5];
    std::cout << "Write single success: addr=0x" << std::hex << reg_addr 
                << ", value=0x" << reg_value << std::endl;
}

void multiple_callback_test(const uint8_t* buffer,int length){
    uint16_t start_addr = (buffer[2] << 8) | buffer[3];
    uint16_t reg_count = (buffer[4] << 8) | buffer[5];
    std::cout << "Write multiple success: start=0x" << std::hex << start_addr 
                << ", count=" << std::dec << reg_count << std::endl;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        std::cout << "Usage: " << argv[0] << " <serial_port> [baud_rate]" << std::endl;
        std::cout << "Example: " << argv[0] << " /dev/ttyUSB0 9600" << std::endl;
        return EXIT_FAILURE;
    }

    const std::string port(argv[1]);
    int baud_rate = (argc >= 3) ? std::stoi(argv[2]) : 9600;

    // modbus接口实例化
    std::unique_ptr<ModbusInterface> modInterface = std::make_unique<ModbusTool>();
    if (!modInterface->start(port, baud_rate)) {
        std::cerr << "Failed to initialize Modbus tool" << std::endl;
        return EXIT_FAILURE;
    }

    // 注册数据接收函数
    modInterface->query_onmsg(query_callback_test);
    modInterface->single_onmsg(single_callback_test);
    modInterface->multiple_onmsg(multiple_callback_test);

    std::cout << "Serial port " << port << " opened at " << baud_rate << " baud" << std::endl;

    // 发送函数测试
    while (running) {
        std::string cmd;
        std::cout << "\nCommands:\n";
        std::cout << "  query    - Query device registers\n";
        std::cout << "  write_s    - Write single SRAM control register\n";
        std::cout << "  write_m    - Write multiple SRAM control registers\n";
        std::cout << "  exit       - Quit program\n";
        std::cout << "Enter command: ";
        
        std::getline(std::cin, cmd);
        
        if (cmd == "query") {
            int start_addr,end_addr;
            std::cout<<"start addr::";
            std::cin>>start_addr;
            std::cout<<"end addr::";
            std::cin>>end_addr;
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            modInterface->query_registers(3, start_addr, end_addr);
        } else if (cmd == "write_s") {
            uint16_t addr, value;
            std::cout << "Enter register address (0-255): ";
            std::cin >> addr;
            std::cout << "Enter value (0-65535): ";
            std::cin >> value;
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            modInterface->write_single_register(3,addr, value);
        } else if (cmd == "write_m") {
            uint16_t start_addr, count;
            std::cout << "Enter start address (0-255): ";
            std::cin >> start_addr;
            std::cout << "Enter register count : ";
            std::cin >> count;
            std::vector<uint16_t> values(count);
            std::cout << "Enter " << count << " values (separated by space): ";
            for (auto& value : values) {
                std::cin >> value;
            }
            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            modInterface->write_multiple_registers(3,start_addr, values);
        } else if(cmd == "exit"){
            modInterface->stop();
            running = false;
        } else if (!cmd.empty()) {
            std::cout << "Unknown command: " << cmd << std::endl;
        } 
    }
    std::cout << "Program exited cleanly" << std::endl;
    
    return EXIT_SUCCESS;
}
